#include <devices_ext/keyboard.h>
#include <util/delay.h>

static SysMsg keyboard;
#define keyboardInt keyboard.mcb
MsgBox keyboardCap;
static pMsgBox tbox = &keyboardCap;
static uint8_t tbl_sz = 0;
static uint8_t *lookup = NULL;

void keyboard_init( void )
{
	ch452_init();
	ch452_write( 0x0201 );
	_delay_us( 50 );
	ch452_write( 0x0422 );//0b0100,0010,0010 设置工作模式 键盘扫描+键盘中断
	cbi( EIMSK, INT4 );
	sbi( EICRB, ISC41 ); //1,0下降沿触发
	cbi( EICRB, ISC40 );
}

static uint8_t translate( uint8_t keycode )
{
	if( lookup == NULL ){
		return keycode;
	}
	uint8_t i;
	for( i = 0; i <= tbl_sz; ++i ){
		if( lookup[i] == keycode )
			return i;
	}
	return tbl_sz;
}

DEF_OSISR( INT4_vect )
{
	enter_kernel();
	cbi( EIMSK, INT4 );
	send_sys_msg_int( tbox, &keyboard );
	enter_task();
}

uint8_t keyboard_getc( void )
{
	keyboard_on();
	wait_msg( tbox );
	return keyboard_byte();
}
int keyboard_read( void *buf, size_t sz )
{
	int i;
	for( i = 0; i < sz; ++i ){
		keyboard_on();
		if( wait_msg( tbox ) == &keyboardInt ){
			ch452_write( 0x0700 );
			((uint8_t *)buf)[i] = translate( ch452_readkey() );
		} else {
			break;
		}
	}
	cbi( EIMSK, INT4 );
	return i;
}

void keyboard_set_notice( pMsgBox mb )
{
	if( mb == NULL ){
		tbox = &keyboardCap;
	} else {
		tbox = mb;
	}
}

uint8_t keyboard_byte( void )
{
	ch452_write( 0x0700 );
	return translate( ch452_readkey() );
}
void keyboard_set_mid( uint8_t id )
{
	keyboard.id = id;
}
void keyboard_set_tbl( uint8_t *tbl, uint8_t sz )
{
	lookup = tbl;
	tbl_sz = sz;
}

#include <stdlib.h>
#include <string.h>
#include <devices_ext/lcd.h>
void keyboard_test( void )
{
	keyboard_init();
	keyboard_set_notice( NULL );
	keyboard_set_tbl( NULL, 0 );
	uint8_t c = 0;
	char info[]="HH.";
	while(True)	{
		keyboard_read( &c, 1 );
		itoa( c, info, 16 );
		strcat( info, "." );
		lcd_poss( 0, 1, info );
	}
}


